package semantic;

import java.awt.List;
import java.io.FileWriter;
import java.io.IOException;

import syntactic.ExpressionNode;

public class SemanticAnalyzer {
	
	private int seqLabel;
	private int seqTemp;
	private FileWriter writer;
	private List labels = new List();
	private List labelSe = new List();
	private List labelFimSe = new List();
	private List labelRepita = new List();
	private List labelFimRepita = new List();
	
	
	
	public SemanticAnalyzer(FileWriter writer)
	{
		this.writer = writer;
	}
	
	private String geraLabel()
	{
		String label = new String("");		
		label = "L" + String.valueOf(seqLabel);
		labels.add(label, seqLabel);
		seqLabel ++;
		return label;
		
	}
	
	public boolean writeSe(String e1, String op, String e2) throws IOException
	{
		labelSe.add(geraLabel());
		labelFimSe.add(geraLabel());
		
		writer.write("if e1 op e2 goto " + (String)(labelSe.getItem(labelSe.getItemCount()-1)) + "; \n");	
		writer.write("goto " + labelFimSe.getItem(labelFimSe.getItemCount()-1) + "; \n");
		writer.write( labelSe.getItem(labelSe.getItemCount()-1) + ": \n");
		labelSe.remove(labelSe.getItemCount()-1);
		
		return true;
	}
	
	public boolean writeFimSe() throws IOException
	{
		writer.write(labelFimSe.getItem(labelFimSe.getItemCount()-1) + ": \n");
		labelFimSe.remove(labelFimSe.getItemCount()-1);
		return true;
	}
	
	public boolean writeRepita() throws IOException
	{
		labelRepita.add(geraLabel());
		labelFimRepita.add(geraLabel());		
		writer.write(labelRepita.getItem(labelRepita.getItemCount()-1) + ": \n");		
		return true;
	}
	
	public boolean writeFimRepita(String e1, String op, String e2) throws IOException
	{
	
		writer.write("if " + e1 + " " + op + " " + e2 + " goto " + labelFimRepita.getItem(labelFimRepita.getItemCount()-1) + "; \n");
		writer.write("goto " + labelRepita.getItem(labelRepita.getItemCount()-1) + "; \n");
		labelRepita.remove(labelRepita.getItemCount()-1);
		writer.write(labelFimRepita + ": \n");
		labelFimRepita.remove(labelFimRepita.getItemCount()-1);
		return true;
	}
	
	public boolean writeAssignment(ExpressionNode assignVar, ExpressionNode expression) throws IOException {
		seqTemp = 0;
		writeExpression(expression);
		
		System.out.println(assignVar.getValue() + " := " + expression.getAddressValue());
		
		return true;
	}
	
	private void writeExpression(ExpressionNode expression) throws IOException {
		if (expression.isOperand()){
			return;
		}
		
		ExpressionNode leftNode = expression.getLeft();
		if (leftNode.isOperator()) {
			writeExpression(leftNode);
		}
		
		ExpressionNode rightNode = expression.getRight();
		if (rightNode.isOperator()) {
			writeExpression(rightNode);
		}
		
		expression.setTemporaryVariable("t" + seqTemp);
		System.out.println(expression.getAddressValue() + " := " + leftNode.getAddressValue() + " " + expression.getValue() + " " + rightNode.getAddressValue());
		
		seqTemp++;
	}

}
